/**
 * Copyright (C) cedarsoft GmbH.
 *
 * Licensed under the GNU General Public License version 3 (the "License")
 * with Classpath Exception; you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *         http://www.cedarsoft.org/gpl3ce
 *         (GPL 3 with Classpath Exception)
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3 only, as
 * published by the Free Software Foundation. cedarsoft GmbH designates this
 * particular file as subject to the "Classpath" exception as provided
 * by cedarsoft GmbH in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 3 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 3 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact cedarsoft GmbH, 72810 Gomaringen, Germany,
 * or visit www.cedarsoft.com if you need additional information or
 * have any questions.
 */

package com.exadel.googleregistrator;

import com.exadel.googleregistrator.bo.AccountBO;
import com.exadel.googleregistrator.bo.impl.AccountBoImpl;
import com.exadel.googleregistrator.entities.Account;
import com.exadel.googleregistrator.verification.Converter;
import com.exadel.googleregistrator.verification.SpeechRecognizer;
import com.exadel.googleregistrator.voicemail.K7Controller;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;

@Service
public class GoogleAccounter implements Registrator {
    public final static String HOME_PAGE = "http://accounts.google.com/SignUp";

    private WebDriver driver;
    private Account currAccount;
    private K7Controller k7Controller;
    private AccountGenerator accountGenerator;
    @Autowired
    private AccountBO accountBO;

    public GoogleAccounter() {
        //driver = new FirefoxDriver();

        k7Controller = new K7Controller();
    }

    public void saveAccount(){
        accountBO.create(currAccount);
        currAccount = accountGenerator.createAccount();
    }

    public boolean isFilled() {
        String temp = driver.findElement(By.id("FirstName")).getText();
        System.out.println(temp);
        return !temp.equals("");
    }

    public URL getCaptcha() {
        if (driver == null) {
            driver = new FirefoxDriver();
            driver.get(HOME_PAGE);
        }
        URL url = null;
        try {
            url = new URL(driver.findElement(By.xpath("//div[@id='recaptcha_image']/img")).getAttribute("src"));
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        return url;
    }

    public URL refreshCaptcha() {
        {
            URL url = null;
            try {
                driver.findElement(By.id("recaptcha_reload_btn")).click();
                url = new URL(driver.findElement(By.xpath("//div[@id='recaptcha_image']/img")).getAttribute("src"));
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            return url;
        }
    }

    public void verify() throws IOException {
        String phoneNumber = k7Controller.getNextPhoneNumber();
        System.out.println(phoneNumber);


        driver.findElement(By.id("idvOptionRadiosCTC")).click();
        Select select = new Select(driver.findElement(By.id("MobileCountry")));
        select.selectByValue("US");
        driver.findElement(By.id("MobileNumber")).sendKeys(phoneNumber);
        driver.findElement(By.id("ctcSubmit")).click();

        SpeechRecognizer recognizer = new SpeechRecognizer();
        Converter converter = new Converter(k7Controller.getLastAudioFileUrl());
        File speechfile = converter.convertToFlac();
        String answer = recognizer.recognizeSpeech(speechfile);
        answer = recognizer.getVerificationCode(answer);
        driver.findElement(By.id("idvGivenAnswer")).sendKeys(answer);
        driver.findElement(By.id("submitbutton")).click();

    }

    public boolean createAccount(String captcha) {
        fillPassword();

        driver.findElement(By.id("recaptcha_response_field")).sendKeys(captcha);
        submit();
        if (driver.getPageSource().contains("recaptcha_response_field"))
            return false; //Капча введена неправильно
        else if (driver.getPageSource().contains("idvOptionRadiosSMS")) {
            try {
                verify();
                if (driver.getPageSource().contains("errormsg_0_MobileNumber")) {

                    return false; //Номер уже использовался
                } else {
                    saveAccount();
                    driver.get(HOME_PAGE);
                    return true; //Верификация прошла успешно
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (driver.getPageSource().contains("submitbutton"))
            return true;  //прошли без верификации
        else return true; //что-то непонятное
        return false;
    }

    private void fillNames() {
        driver.findElement(By.id("FirstName")).sendKeys(currAccount.getFirstName());
        driver.findElement(By.id("LastName")).sendKeys(currAccount.getLastName());
        driver.findElement(By.id("GmailAddress")).sendKeys(currAccount.getUsername());
    }

    private void fillPassword() {
        driver.findElement(By.id("Passwd")).sendKeys(currAccount.getPassword());
        driver.findElement(By.id("PasswdAgain")).sendKeys(currAccount.getPassword());
    }

    private void fillBirthday() {
        driver.findElement(By.id("BirthMonth")).click();
        Date birthDate = currAccount.getBirthDate();
        driver.findElement(By.id(":" + Integer.toHexString(birthDate.getMonth()))).click();
        driver.findElement(By.id("BirthDay")).sendKeys(birthDate.getDay() + "");
        driver.findElement(By.id("BirthYear")).sendKeys(birthDate.getYear() + "");
    }

    private void fillGender() {
        String gender = currAccount.getGender();
        driver.findElement(By.id("Gender")).click();
        if (gender.equalsIgnoreCase("male")){
            driver.findElement(By.id(":c")).click();
        } else {
            driver.findElement(By.id(":d")).click();
        }
    }

    private void fillCountry() {
        driver.findElement(By.id("CountryCode")).click();
        driver.findElement(By.id(":5x")).click();
    }

    private void agreeTerms() {
        driver.findElement(By.id("TermsOfService")).click();
    }

    private void submit() {
        driver.findElement(By.id("submitbutton")).click();
    }

    public void rerunDriver(){
        driver = new FirefoxDriver();
    }

    public void fillFields() {
        try {
            if (!isFilled()) {
                fillNames();
                fillBirthday();
                fillCountry();
                fillGender();
                agreeTerms();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}